﻿using AutoMapper;
using mozhi.smarterp.Finance.Accounts.Repository;
using mozhi.smarterp.Finance.Enums;
using mozhi.smarterp.Finance.Finances.Repository;
using mozhi.smarterp.Finance.Querys;
using Mozhi.Abp.Core.Extensions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Guids;

namespace mozhi.smarterp.Finance.Finances
{
    public class EndPeriodProcessItemAppService : FinanceAppService, IEndPeriodProcessItemAppService
    {
        private IEndPeriodProcessItemRepository _repository;
        private IGuidGenerator _guidGenerator;
        private IAccountRepository _accountRepository;

        public EndPeriodProcessItemAppService(IEndPeriodProcessItemRepository repository, IGuidGenerator guidGenerator ,
            IAccountRepository accountRepository) 
        {
            _repository = repository;
            _guidGenerator = guidGenerator;
            _accountRepository = accountRepository;
        }

        public async Task<List<EndPeriodProcessItemDto>> LoadDefaultAsync(AccountingStandardType accountingStandard)
        {
            //如果存在，则删除掉原有的数据
            var oldItems = await _repository.FindAsync(new PageQuery() { PageIndex = 1, PageSize = int.MaxValue });

            if (oldItems.Count > 0)
                await _repository.DeleteAsync(oldItems);

            var items = GetDefaultEndPeriodProcessItems(accountingStandard);

            if(items==null || items.Count==0)
                throw new ArgumentNullException("items");

            items = await _repository.InsertAsync(items);

            return ObjectMapper.Map<List<EndPeriodProcessItem>, List<EndPeriodProcessItemDto>>(items);
        }


        public async Task<PagedResultDto<EndPeriodProcessItemDto>> FindAsync(EndPeriodProcessItemPageQuery query)
        {
            //var items = await _repository.FindAsync(query);

            //var count = await _repository.GetCountAsync(query);

            //var result = new PagedResultDto<EndPeriodProcessItemDto>();

            //var datas = ObjectMapper.Map<List<EndPeriodProcessItem>, List<EndPeriodProcessItemDto>>(items);

            ////不是12排除掉结转销售利润
            //if (query.Period.HasValue && query.Period.Value.ToFirstDayDateTime().Month != 12)
            //    datas = datas.Where(x => x.Index != 8).ToList();

            //if (!query.IncludeDetail)
            //{
            //    result.TotalCount = count;
            //    result.Items = datas;
            //    return result;
            //}

            //var settings = datas.Where(x => x.Settings != null).Select(x => x.Settings).ToList().Join();

            //var accountCodes = settings.Where(x => !x.CustomAccountCode.IsNullOrEmpty())
            //    .Select(x => x.CustomAccountCode).Distinct().ToList();

            //var accounts = await _accountRepository.FindAsync(new AccountQuery() { Codes = accountCodes });

            //settings.ForEach(setting =>
            //{
            //    var match = accounts.FirstOrDefault(x => x.Code == setting.CustomAccountCode);
            //    setting.CustomAccountName = match?.Code + " " + match.Name;
            //    setting.CustomAccountId = match?.Id;
            //});

            //return result;
            throw new NotImplementedException();
        }

        public async Task<EndPeriodProcessItemDto> GetAsync(Guid id)
        {
            //var item = await _repository.FindAsync(id , true);

            //if (item == null)
            //    throw new UserFriendlyException("期末处理项不存在", "100000");

            //var result = ObjectMapper.Map<EndPeriodProcessItem, EndPeriodProcessItemDto>(item);

            //var accountCodes = result.Settings?.Select(x=>x.CustomAccountCode).ToList();

            //var accounts = await _accountRepository.FindAsync(new AccountQuery() { Codes = accountCodes });

            //result.Settings.ForEach(setting =>
            //{
            //    var match = accounts.FirstOrDefault(x => x.Code == setting.CustomAccountCode);
            //    setting.CustomAccountName = match?.Code + " " + match.Name;
            //    setting.CustomAccountId = match?.Id;
            //});

            //return result;
            throw new NotImplementedException();
        }

        public async Task<EndPeriodProcessItemDto> UpdateAsync(EndPeriodProcessItemUpdateDto dto)
        {
            //var settings = dto?.Settings;

            //if(settings==null)
            //    throw new UserFriendlyException("期末处理项设置内容不能为空", "100000");

            //var accountIds = settings.Select(x=>x.CustomAccountId).Distinct().ToList();

            //var accounts = await _accountRepository.FindAsync(new AccountQuery() { Ids = accountIds });

            //var item = await _repository.GetAsync(dto.Id, true);

            //if (item == null)
            //    throw new UserFriendlyException("期末处理项不存在", "100000");

            //foreach(var setting in settings)
            //{
            //    var matchAccount = accounts.FirstOrDefault(x => x.Id == setting.CustomAccountId);

            //    if (matchAccount == null)
            //        throw new UserFriendlyException($"科目：{setting.CustomAccountId}不存在", "100000");

            //    if (!matchAccount.Activated)
            //        throw new UserFriendlyException($"科目：{matchAccount.FullName}已禁用", "100000");

            //    var matchSetting = item.Settings.FirstOrDefault(x => x.Id == setting.Id);

            //    if (matchSetting == null)
            //        throw new UserFriendlyException($"设置项：{setting.Id}不存在", "100000");

            //    matchSetting.ChangeCustomAccountCode(matchAccount.Code);
            //}

            //item = await _repository.UpdateAsync(item);

            //return ObjectMapper.Map<EndPeriodProcessItem, EndPeriodProcessItemDto>(item);
            throw new NotImplementedException();
        }

        public async Task<bool> DeleteAsync(Guid id)
        {
            await _repository.DeleteAsync(id);

            return true;
        }

        #region
        private List<EndPeriodProcessItem> GetDefaultEndPeriodProcessItems(AccountingStandardType accountingStandardType)
        {
            var items = new List<EndPeriodProcessItem>();

            //结转销售成本
            var carryOverSalesCostItem = new EndPeriodProcessItem(_guidGenerator.Create() , "结转销售成本",1);

            var carryOverSalesCostItemSettings =new List<EndPeriodProcessItemSetting>();

            if(accountingStandardType== AccountingStandardType.BusinessEnterprises)
            {
                carryOverSalesCostItemSettings.AddRange(new List<EndPeriodProcessItemSetting>() 
                { 
                    new EndPeriodProcessItemSetting(_guidGenerator.Create(), carryOverSalesCostItem.Id, "主营业务收入", "6001", "6001", 1),
                    new EndPeriodProcessItemSetting(_guidGenerator.Create(), carryOverSalesCostItem.Id, "主营业务成本", "6401", "6401", 2),
                    new EndPeriodProcessItemSetting(_guidGenerator.Create(), carryOverSalesCostItem.Id, "库存商品", "1405", "1405", 3),
                });
            }
            else
            {
                carryOverSalesCostItemSettings.AddRange(new List<EndPeriodProcessItemSetting>()
                {
                    new EndPeriodProcessItemSetting(_guidGenerator.Create(), carryOverSalesCostItem.Id, "主营业务收入", "5001", "5001", 1),
                    new EndPeriodProcessItemSetting(_guidGenerator.Create(), carryOverSalesCostItem.Id, "主营业务成本", "5401", "5401", 2),
                    new EndPeriodProcessItemSetting(_guidGenerator.Create(), carryOverSalesCostItem.Id, "库存商品", "1405", "1405", 3),
                });
            }
            carryOverSalesCostItem.AddSettings(carryOverSalesCostItemSettings);
            items.Add(carryOverSalesCostItem);


            //计提折旧
            var depreciationAccrualItem = new EndPeriodProcessItem(_guidGenerator.Create(), "计提折旧", 2);

            var depreciationAccrualItemSettings = new List<EndPeriodProcessItemSetting>();

            if (accountingStandardType == AccountingStandardType.BusinessEnterprises)
            {
                depreciationAccrualItemSettings.AddRange(new List<EndPeriodProcessItemSetting>()
                {
                    new EndPeriodProcessItemSetting(_guidGenerator.Create(), carryOverSalesCostItem.Id, "折旧-费用类科目", "6602.05", "6602.05", 1),
                    new EndPeriodProcessItemSetting(_guidGenerator.Create(), carryOverSalesCostItem.Id, "累计折旧", "1602", "1602", 2),
                });
            }
            else
            {
                depreciationAccrualItemSettings.AddRange(new List<EndPeriodProcessItemSetting>()
                {
                    new EndPeriodProcessItemSetting(_guidGenerator.Create(), carryOverSalesCostItem.Id, "折旧-费用类科目", "6602.05", "5602.05", 1),
                    new EndPeriodProcessItemSetting(_guidGenerator.Create(), carryOverSalesCostItem.Id, "累计折旧", "1602", "1602", 2),
                });
            }
            depreciationAccrualItem.AddSettings(depreciationAccrualItemSettings);
            items.Add(depreciationAccrualItem);

            //摊销长期待摊费用
            var amortizeLongTermPrepaidExpensesItem = new EndPeriodProcessItem(_guidGenerator.Create(), "摊销长期待摊费用", 3);
            var amortizeLongTermPrepaidExpensesItemSettings = new List<EndPeriodProcessItemSetting>();

            if (accountingStandardType == AccountingStandardType.BusinessEnterprises)
            {
                amortizeLongTermPrepaidExpensesItemSettings.AddRange(new List<EndPeriodProcessItemSetting>()
                {
                    new EndPeriodProcessItemSetting(_guidGenerator.Create(), amortizeLongTermPrepaidExpensesItem.Id, "长期待摊-费用类科目", "6602.07", "6602.07", 1),
                    new EndPeriodProcessItemSetting(_guidGenerator.Create(), amortizeLongTermPrepaidExpensesItem.Id, "长期待摊费用", "1801", "1801", 2),
                });
            }
            else
            {
                amortizeLongTermPrepaidExpensesItemSettings.AddRange(new List<EndPeriodProcessItemSetting>()
                {
                    new EndPeriodProcessItemSetting(_guidGenerator.Create(), amortizeLongTermPrepaidExpensesItem.Id, "长期待摊-费用类科目", "6602.07", "5602.07", 1),
                    new EndPeriodProcessItemSetting(_guidGenerator.Create(), amortizeLongTermPrepaidExpensesItem.Id, "长期待摊费用", "1801", "1801", 2),
                });
            }
            amortizeLongTermPrepaidExpensesItem.AddSettings(amortizeLongTermPrepaidExpensesItemSettings);
            items.Add(amortizeLongTermPrepaidExpensesItem);

            //期末调汇
            var closingExchangeRateAdjustmentItem = new EndPeriodProcessItem(_guidGenerator.Create(), "期末调汇", 4);
            var closingExchangeRateAdjustmentItemSettings = new List<EndPeriodProcessItemSetting>();

            if (accountingStandardType == AccountingStandardType.BusinessEnterprises)
            {
                closingExchangeRateAdjustmentItemSettings.AddRange(new List<EndPeriodProcessItemSetting>()
                {
                    new EndPeriodProcessItemSetting(_guidGenerator.Create(), closingExchangeRateAdjustmentItem.Id, "汇兑损益", "6603.02", "6603.02", 1),
                });
            }
            else
            {
                closingExchangeRateAdjustmentItemSettings.AddRange(new List<EndPeriodProcessItemSetting>()
                {
                    new EndPeriodProcessItemSetting(_guidGenerator.Create(), closingExchangeRateAdjustmentItem.Id, "汇兑损益", "6603.02", "5603.02", 1),
                });
            }
            closingExchangeRateAdjustmentItem.AddSettings(closingExchangeRateAdjustmentItemSettings);
            items.Add(closingExchangeRateAdjustmentItem);

            //结转未交增值税
            var carryForwardUnpaidVATItem = new EndPeriodProcessItem(_guidGenerator.Create(), "结转未交增值税", 5);
            var carryForwardUnpaidVATItemSettings = new List<EndPeriodProcessItemSetting>();

            if (accountingStandardType == AccountingStandardType.BusinessEnterprises)
            {
                carryForwardUnpaidVATItemSettings.AddRange(new List<EndPeriodProcessItemSetting>()
                {
                    new EndPeriodProcessItemSetting(_guidGenerator.Create(), carryForwardUnpaidVATItem.Id, "应交增值税（金额测算）", "2221.01", "2221.01", 1),
                    new EndPeriodProcessItemSetting(_guidGenerator.Create(), carryForwardUnpaidVATItem.Id, "应交增值税（凭证科目）", "2221.01.03", "2221.01.03", 2),
                    new EndPeriodProcessItemSetting(_guidGenerator.Create(), carryForwardUnpaidVATItem.Id, "未交增值税", "2221.02", "2221.02", 3),
                });
            }
            else
            {
                carryForwardUnpaidVATItemSettings.AddRange(new List<EndPeriodProcessItemSetting>()
                {
                    new EndPeriodProcessItemSetting(_guidGenerator.Create(), carryForwardUnpaidVATItem.Id, "应交增值税（金额测算）", "2221.01", "2221.01", 1),
                    new EndPeriodProcessItemSetting(_guidGenerator.Create(), carryForwardUnpaidVATItem.Id, "应交增值税（凭证科目）", "2221.01.03", "2221.01.03", 2),
                    new EndPeriodProcessItemSetting(_guidGenerator.Create(), carryForwardUnpaidVATItem.Id, "未交增值税", "2221.02", "2221.02", 3),
                });
            }
            carryForwardUnpaidVATItem.AddSettings(carryForwardUnpaidVATItemSettings);
            items.Add(carryForwardUnpaidVATItem);

            //累计所得税
            var accrualIncomeTaxItem = new EndPeriodProcessItem(_guidGenerator.Create(), "累计所得税", 6);
            var accrualIncomeTaxItemSettings = new List<EndPeriodProcessItemSetting>();

            if (accountingStandardType == AccountingStandardType.BusinessEnterprises)
            {
                accrualIncomeTaxItemSettings.AddRange(new List<EndPeriodProcessItemSetting>()
                {
                    new EndPeriodProcessItemSetting(_guidGenerator.Create(), accrualIncomeTaxItem.Id, "所得税费用", "6801", "6801", 1),
                    new EndPeriodProcessItemSetting(_guidGenerator.Create(), accrualIncomeTaxItem.Id, "应交所得税", "2221.06", "2221.06", 2),
                    new EndPeriodProcessItemSetting(_guidGenerator.Create(), accrualIncomeTaxItem.Id, "本年利润", "4103", "4103", 3),
                });
            }
            else
            {
                accrualIncomeTaxItemSettings.AddRange(new List<EndPeriodProcessItemSetting>()
                {
                    new EndPeriodProcessItemSetting(_guidGenerator.Create(), accrualIncomeTaxItem.Id, "所得税费用", "6801", "5801", 1),
                    new EndPeriodProcessItemSetting(_guidGenerator.Create(), accrualIncomeTaxItem.Id, "应交所得税", "2221.06", "2221.06", 2),
                    new EndPeriodProcessItemSetting(_guidGenerator.Create(), accrualIncomeTaxItem.Id, "本年利润", "4103", "3103", 3),
                });
            }
            accrualIncomeTaxItem.AddSettings(accrualIncomeTaxItemSettings);
            items.Add(accrualIncomeTaxItem);

            //结转损益
            var carryForwardProfitLossItem = new EndPeriodProcessItem(_guidGenerator.Create(), "结转损益", 7);
            var carryForwardProfitLossItemSettings = new List<EndPeriodProcessItemSetting>();

            if (accountingStandardType == AccountingStandardType.BusinessEnterprises)
            {
                carryForwardProfitLossItemSettings.AddRange(new List<EndPeriodProcessItemSetting>()
                {
                    new EndPeriodProcessItemSetting(_guidGenerator.Create(), carryForwardProfitLossItem.Id, "本年利润", "4103", "4103", 1),
                });
            }
            else
            {
                carryForwardProfitLossItemSettings.AddRange(new List<EndPeriodProcessItemSetting>()
                {
                    new EndPeriodProcessItemSetting(_guidGenerator.Create(), carryForwardProfitLossItem.Id, "本年利润", "4103", "3103", 1),
                });
            }
            carryForwardProfitLossItem.AddSettings(carryForwardProfitLossItemSettings);
            items.Add(carryForwardProfitLossItem);

            //结转未分配利润
            var carryForwardUndistributedProfitsItem =new EndPeriodProcessItem(_guidGenerator.Create(), "结转未分配利润", 8);
            var carryForwardUndistributedProfitsItemSettings = new List<EndPeriodProcessItemSetting>();

            if (accountingStandardType == AccountingStandardType.BusinessEnterprises)
            {
                carryForwardUndistributedProfitsItemSettings.AddRange(new List<EndPeriodProcessItemSetting>()
                {
                    new EndPeriodProcessItemSetting(_guidGenerator.Create(), carryForwardUndistributedProfitsItem.Id, "本年利润", "4103", "4103", 1),
                    new EndPeriodProcessItemSetting(_guidGenerator.Create(), carryForwardUndistributedProfitsItem.Id, "利润分配-未分配利润", "4104.07", "4104.07", 2),
                });
            }
            else
            {
                carryForwardUndistributedProfitsItemSettings.AddRange(new List<EndPeriodProcessItemSetting>()
                {
                    new EndPeriodProcessItemSetting(_guidGenerator.Create(), carryForwardUndistributedProfitsItem.Id, "本年利润", "4103", "3103", 1),
                    new EndPeriodProcessItemSetting(_guidGenerator.Create(), carryForwardUndistributedProfitsItem.Id, "利润分配-未分配利润", "4104.07", "3104.07", 2),
                });
            }
            carryForwardUndistributedProfitsItem.AddSettings(carryForwardUndistributedProfitsItemSettings);
            items.Add(carryForwardUndistributedProfitsItem);

            return items;

        }
        #endregion
    }
}
